package java_thinking.unit_10._10_11;

/**
 * @Description : 局部内部类与匿名内部类的创建比较
 * @author: cww
 * @DateTime: 2019-03-16 19:47
 */
public interface Counter {
    int next();
}

class LocalInnerClass{
    private int count = 0;

    /**
     * 使用局部内部类的写法
     * @param name 内部类如果要使用外围传入的参数就必须是final
     * @return
     */
    Counter getCounter(final String name){
        //一个局部内部类(典型是在方法体里面创建)，属于闭包。内部类使用外围变量必须是final

        class LocalCounter implements Counter{
            public LocalCounter(){
                //局部内部类可以有构造函数
                System.out.println("LocalCounter()");
            }
            @Override
            public int next() {
                System.out.println(name);
                return count++;
            }
        }
        return new LocalCounter();
    }

    /**
     * 不用局部内部类的写法
     * name不需要像匿名内部类的写法final
     * @param name
     * @return
     */
    Counter getCounter1(String name) {
        return new LocalCounter1(name);
    }
    class LocalCounter1 implements Counter{
        private String name;
        public LocalCounter1(String name){
            this.name = name;
            System.out.println("Normal InnerCounter Constructor");
        }
        @Override
        public int next() {
            System.out.println(name);
            return count++;
        }
    }

    /**
     * 匿名内部类写法
     * @param name
     * @return
     */
    Counter getCounter2(final String name) {
        return new Counter() {
            //匿名内部类不可能有命名的构造函数，因为这个类是匿名的，仅可以有实例初始化
            {
                System.out.println("Counter()");
            }
            @Override
            public int next() {
                System.out.println(name);
                return count++;
            }
        };
    }

    public static void main(String[] args) {
        LocalInnerClass localInnerClass = new LocalInnerClass();
        Counter c1 = localInnerClass.getCounter1("counter1");
        Counter c2 = localInnerClass.getCounter("counter");
        Counter c3 = localInnerClass.getCounter2("counter2");
        for (int i =0;i<5;i++){
            System.out.println(c1.next());
        }
        for (int i=0;i<5;i++){
            System.out.println(c2.next());
        }
    }
}
